#include "bsp_soft_iic.h"

/*******************************************************************************
* 函数功能 : 产生IIC起始信号   
* 输    入 : iic设备句柄
* 输    出 : 无
*******************************************************************************/
void soft_iic_start(soft_iic_dev_t *dev){
	dev->SDA_OUT();
	dev->SDA_H();
	dev->SCK_H();
	dev->delay();
	dev->SDA_L();//SCL为高时候，SDA从高到低的跳变产生开始信号
	dev->delay();
	dev->SCK_L();
	dev->delay();
}
/*******************************************************************************
* 函数功能 : 产生IIC停止信号   
* 输    入 : iic设备句柄
* 输    出 : 无
*******************************************************************************/
void soft_iic_stop(soft_iic_dev_t *dev){
	dev->SDA_OUT();
	dev->SDA_L();
	dev->delay();
	dev->SCK_H();
	dev->delay();
	dev->SDA_H();
	dev->delay();
}
/*******************************************************************************
* 函数功能 : 等待ACK响应
* 输    入 : iic设备句柄
* 输    出 : 无
*******************************************************************************/
uint8_t soft_iic_wait_ack(soft_iic_dev_t *dev){
	uint8_t tick = 0;
	dev->SDA_H();//先把SDA拉高，如果从机把SDA拉低了，就表示接收到应答信号了
	dev->SDA_IN();
	dev->delay();
	dev->SCK_H();
	dev->delay();
	while (dev->SDA_READ()){
		tick++;
		if(tick > 250){
			soft_iic_stop(dev);
			return 1;
		}
	}
	dev->SCK_L();
	dev->delay();
	return 0;
}
/*******************************************************************************
* 函数功能 : ACK响应
* 输    入 : iic设备句柄
* 输    出 : 无
*******************************************************************************/
void soft_iic_ack(soft_iic_dev_t *dev){
	dev->SDA_OUT();
	dev->SDA_L();
	dev->delay();
	dev->SCK_H();
	dev->delay();
	dev->SCK_L();
	dev->delay();
	dev->SDA_H();
	dev->delay();
}
/*******************************************************************************
* 函数功能 : NACK响应
* 输    入 : iic设备句柄
* 输    出 : 无
*******************************************************************************/
void soft_iic_nack(soft_iic_dev_t *dev){
	dev->SDA_OUT();
	dev->SDA_H();
	dev->delay();
	dev->SCK_H();
	dev->delay();
	dev->SCK_L();
	dev->delay();
}
/*******************************************************************************
* 函数功能 : 读取一个字节
* 输    入 : iic设备句柄
* 输    出 : 字节值
*******************************************************************************/
uint8_t soft_iic_read_byte(soft_iic_dev_t *dev, uint8_t ack){
	uint8_t ch = 0;
	dev->SDA_IN();
	for(int i=0;i<8;i++){
		dev->SCK_H();
		dev->delay();
		ch <<= 1;
		if(dev->SDA_READ()){
			ch++;
		}
		else{
			dev->delay();
		}
		dev->SCK_L();
		dev->delay();
	}
	if(!ack){
		soft_iic_nack(dev);
	}
	else{
		soft_iic_ack(dev);
	}
	return ch;
}
/*******************************************************************************
* 函数功能 : 写入一个字节
* 输    入 : iic设备句柄，写入的字节值
* 输    出 : 无
*******************************************************************************/
void soft_iic_send_byte(soft_iic_dev_t *dev, uint8_t ch){
	dev->SDA_OUT();
	for(int i=0;i<8;i++){
		if((ch&0x80)){
			dev->SDA_H();
		}
		else{
			dev->SDA_L();
		}
		dev->delay();
		ch <<= 1;//高位先发送
		dev->SCK_H();
		dev->delay();
		dev->SCK_L();
	}
	dev->SDA_H();
}
